package device

import (
	"backend/internal/common/errorx"
	modbusTypes "backend/internal/core/types"
	"backend/internal/db/model"
	"context"
	"errors"
	"fmt"
	"gorm.io/gorm"
	"net/http"

	"backend/internal/svc"
	"backend/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

type EditDeviceLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewEditDeviceLogic(ctx context.Context, svcCtx *svc.ServiceContext) *EditDeviceLogic {
	return &EditDeviceLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *EditDeviceLogic) EditDevice(req *types.EditDeviceReq) (resp *types.EditDeviceResp, err error) {
	// 1. 校验必要字段（如设备ID）
	logx.Debugf("deviceID: %d", req.DeviceID)
	if req.DeviceID == 0 {
		return nil, errorx.NewCodeError(http.StatusBadRequest, "设备ID不能为空")
	}

	// 2. 查询设备是否存在
	var device model.Device
	result := l.svcCtx.GormDB.Where("id = ?", req.DeviceID).First(&device)
	if result.Error != nil {
		if errors.Is(result.Error, gorm.ErrRecordNotFound) {
			return nil, errorx.NewCodeError(404, "设备不存在")
		}
		errorStr := fmt.Sprintf("查询设备失败: %v", result.Error)
		logx.Errorf(errorStr)
		return nil, errorx.NewCodeError(http.StatusInternalServerError, errorStr)
	}

	// 更新modbus客户端
	err = l.svcCtx.ClientManager.EditClient(device.Name, modbusTypes.ProtocolType(req.Protocol), req.DeviceName, req.IP, req.Port)
	if err != nil {
		logx.Errorf("更新modbus客户端失败: %v", err)
		return nil, errorx.NewCodeError(http.StatusInternalServerError, "更新modbus客户端失败")
	}

	logx.Debugf("更新实际modbus客户端成功 deviceName: %s, ip: %s, port: %d, protocol: %s", req.DeviceName, req.IP, req.Port, req.Protocol)

	// 3. 更新字段（仅更新非零值字段）
	updates := make(map[string]interface{})
	if req.DeviceName != "" {
		updates["name"] = req.DeviceName
	}
	if req.IP != "" {
		updates["ip"] = req.IP
	}
	if req.Port != 0 {
		updates["port"] = int32(req.Port)
	}
	if req.Protocol != "" {
		updates["protocol"] = req.Protocol
	}

	// 4. 执行更新
	result = l.svcCtx.GormDB.Model(&device).Updates(updates)
	if result.Error != nil {
		errorStr := fmt.Sprintf("更新设备失败: %v", result.Error)
		logx.Errorf(errorStr)
		return nil, errorx.NewCodeError(http.StatusInternalServerError, errorStr)
	}

	logx.Infof("更新设备成功: ID=%d", req.DeviceID)

	// 5. 返回成功响应
	return &types.EditDeviceResp{
		Status: http.StatusOK,
		Msg:    fmt.Sprintf("更新设备成功: ID=%d", req.DeviceID),
		Data:   true,
	}, nil
}
